/* eslint-disable no-unused-vars */
<template lang="pug">
  .m-content
    .title 配置流程
    .bodyer
      .palette-group
        .group-title 元件库
        .comp(@click="baseComp=!baseComp")
          i(class="el-icon-arrow-right" :class="{'is-active':baseComp}")
          | 基本元件
        .comp-content(ref="baseCompContent" v-show="baseComp" :style="baseStyleObject")
        .comp(@click="presetComp=!presetComp")
          i(class="el-icon-arrow-right" :class="{'is-active':presetComp}")
          | 预置元件
        .comp-content(ref="presetCompContent" v-show="presetComp")
      .diagramContent
        .diagram(ref="diagram")
        .btns
          el-button(type="primary" @click="save") 保存
          el-button 取消
        .contextMenu(ref="contextMenu" v-show="contextMenu")
          ul
            li(v-for="item in contextMenus")
              a(href="javascript:;" @click="item.handleClick")
                i(:class="item.icon")
                | {{item.desc}}

</template>
<script>
import ElCollapseTransition from 'element-ui/lib/transitions/collapse-transition'
import icons from '@/utils/icon.js'
let myPalettes = [
  { text: '开始', geo: 'kaishi', category: 'Start' },
  { geo: 'jieshu', text: '结束', category: 'End' },
  { geo: 'tiaojian', text: '条件', category: 'Conditional' },
  { geo: 'shujuyunsuan', text: '数据运算', category: 'Calculation' },
  { geo: 'shujuzhuanhuan', text: '数据转换', category: 'Transformation' }
]

let presetComp = [
  { geo: 'yuzhiyuanjian', text: '创建vpc', category: 'database' }
]

const Link = {
  type: '',
  target: '', // 目标节点 id 即 Node.id

  meta: ''
}

class ContextMenusComp {
  constructor () {
    this.desc = '查看'
    this.icon = 'iconfont icon-chakan'
    this.handleClick = 'getdata'
  }
}
const contextMenus = [{ desc: '查看', icon: 'iconfont icon-chakan', handleClick: 'getdata' }]
/* eslint-disable no-undef */
if (window.goSamples) goSamples()

export default {
  components: { ElCollapseTransition },
  data () {
    return {
      baseStyleObject: {
        height: myPalettes.length * 75 + 'px'
      },
      $: null,
      myDiagram: null,
      baseComp: true,
      presetComp: true,
      contextMenu: false,
      contextMenus: [
        { desc: '查看', icon: 'iconfont icon-chakan', handleClick: this.getdata },
        { desc: '数据配置', icon: 'iconfont icon-shujuyunsuan', handleClick: this.condition },
        { desc: '节点条件入参', icon: 'iconfont icon-chakan', handleClick: this.nodeInData },
        { desc: '数据运算', icon: 'iconfont icon-chakan', handleClick: this.arithmetic },
        { desc: '自定义转换', icon: 'iconfont icon-chakan', handleClick: this.customConversion },
        { desc: '删除', icon: 'iconfont icon-chakan', handleClick: this.getdata }
      ]
    }
  },

  mounted () {
    this.$ = go.GraphObject.make
    this.myDiagram = this.$(go.Diagram, this.$refs.diagram,
      {
        initialContentAlignment: go.Spot.Center,
        allowDrop: true,
        'LinkDrawn': this.showLinkLabel,
        'LinkRelinked': this.showLinkLabel,
        scrollsPageOnFocus: false,
        'undoManager.isEnabled': true,
        grid: this.$(go.Panel, 'Grid',
          { gridCellSize: new go.Size(8, 8) },
          this.$(go.Shape, 'LineH', { stroke: '#f1f1f1' }),
          this.$(go.Shape, 'LineV', { stroke: '#f1f1f1' })
        )
      })
    this.init()

    /**
    * 连线事件
    */
    this.myDiagram.addDiagramListener('LinkDrawn', (e) => {
      var link = e.subject
      this.updateNode(link.data)
      console.log(link.data)
      // let linkData = link.data
      // setTimeout(() => {
      //   this.myDiagram.model.removeLinkData(linkData)
      // }, 3000)
    })

    /**
    * 删除线和节点事件
    */
    this.myDiagram.addDiagramListener('SelectionDeleting', function (e) {
      e.subject.each(function (n) {
        // n为删除节点或线的对象
        console.log(n.data)
        // if (n.data.key == '5.1') {
        //   // 不允许删除，给e.cancel赋值
        //   e.cancel = true
        // }
      })
    })
  },
  methods: {
    init () {
      let myContextMenu = this.$(go.HTMLInfo, {
        show: this.showContextMenu,
        mainElement: this.$refs.contextMenu
      })

      // 去除鼠标右键
      this.$refs.contextMenu.addEventListener('contextmenu', function (e) {
        e.preventDefault()
        return false
      }, false)
      // Node.location来自节点数据的“loc”属性，
      // 通过Point.parse静态方法转换。
      // 如果改变了Node.location，则更新节点数据的“loc”属性，
      // 使用Point.stringify静态方法进行转换。

      function nodeStyle () {
        return [
          new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
          {
            locationSpot: go.Spot.Center
          }
        ]
      }

      // 节点一些属性
      function makePort (name, align, spot, output, input) {
        var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom)
        return this.$(go.Shape,
          {
            fill: 'transparent',
            strokeWidth: 0,
            width: horizontal ? 40 : 8,
            height: !horizontal ? 70 : 8,
            alignment: align,
            stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),
            portId: name,
            fromSpot: spot,
            fromLinkable: output,
            toSpot: spot,
            toLinkable: input,
            cursor: 'pointer',
            mouseEnter: function (e, port) { // the PORT argument will be this Shape
              if (!e.diagram.isReadOnly) port.fill = 'rgba(255,0,255,0.5)'
            },
            mouseLeave: function (e, port) {
              port.fill = 'transparent'
            }
          })
      }

      // 字体
      function textStyle () {
        return {
          font: '12px MicrosoftYaHei',
          stroke: '#666666',
          margin: new go.Margin(48, 0, 0, 0)
        }
      }

      // 填充样式
      function fillStyle () {
        return {
          strokeWidth: 0, width: 45, height: 34, fill: 'rgba(31, 96, 189, 0.05)'
        }
      }

      function iconStyle () {
        return {
          strokeWidth: 0, width: 25, height: 25, fill: '#1f60bd', margin: new go.Margin(8, 0, 0, 0)
        }
      }

      // 修改文档时，在标题中添加 *
      this.myDiagram.addDiagramListener('Modified', function (e) {
        var idx = document.title.indexOf('*')
        if (idx < 0) document.title += '*'
      })

      // 默认节点
      this.myDiagram.nodeTemplateMap.add('',
        this.$(go.Node, 'Auto', nodeStyle(),
          { contextMenu: myContextMenu },
          this.$(go.Panel, 'Auto',
            this.$(go.Shape, 'Rectangle', fillStyle()),
            this.$(go.Shape, 'Rectangle', iconStyle(),
              new go.Binding('geometry', 'geo', this.geoFunc))
          ),
          this.$(go.TextBlock, textStyle(), new go.Binding('text').makeTwoWay()),
          // three named ports, one on each side except the top, all output only:
          makePort.call(this, 'T', go.Spot.Top, go.Spot.Top, true, true),
          makePort.call(this, 'L', go.Spot.Left, go.Spot.Left, true, true),
          makePort.call(this, 'R', go.Spot.Right, go.Spot.Right, true, true),
          makePort.call(this, 'B', go.Spot.Bottom, go.Spot.Bottom, true, true)
        ))

      // 结束
      this.myDiagram.nodeTemplateMap.add('End',
        this.$(go.Node, 'Auto', nodeStyle(),
          this.$(go.Panel, 'Auto',
            this.$(go.Shape, 'Rectangle', fillStyle()),
            this.$(go.Shape, 'Rectangle', iconStyle(),
              new go.Binding('geometry', 'geo', this.geoFunc))
          ),
          this.$(go.TextBlock, textStyle(), new go.Binding('text').makeTwoWay()),
          makePort.call(this, 'T', go.Spot.Top, go.Spot.Top, false, true),
          makePort.call(this, 'L', go.Spot.Left, go.Spot.Left, false, true),
          makePort.call(this, 'R', go.Spot.Right, go.Spot.Right, false, true)
        ))
      //  条件
      this.myDiagram.nodeTemplateMap.add('Conditional',
        this.$(go.Node, 'Auto', nodeStyle(),
          this.$(go.Panel, 'Auto',
            this.$(go.Shape, 'Diamond', {
              margin: 0, strokeWidth: 0, width: 60, height: 50, fill: 'rgba(31, 96, 189, 0.05)'
            }),
            this.$(go.Shape, 'Rectangle', iconStyle(),
              new go.Binding('geometry', 'geo', this.geoFunc))
          ),
          this.$(go.TextBlock, textStyle(),
            new go.Binding('text').makeTwoWay()),
          // four named ports, one on each side:
          makePort.call(this, 'T', go.Spot.Top, go.Spot.Top, false, true),
          makePort.call(this, 'L', go.Spot.Left, go.Spot.Left, true, true),
          makePort.call(this, 'R', go.Spot.Right, go.Spot.Right, true, true),
          makePort.call(this, 'B', go.Spot.Bottom, go.Spot.Bottom, true, false)
        ))

      // 线条
      this.myDiagram.linkTemplate =
        this.$(go.Link,
          {
            routing: go.Link.AvoidsNodes,
            curve: go.Link.JumpOver,
            corner: 5,
            toShortLength: 4,
            relinkableFrom: true,
            relinkableTo: true,
            reshapable: true,
            resegmentable: true,
            mouseEnter: function (e, link) { link.findObject('HIGHLIGHT').stroke = 'rgba(30,144,255,0.2)' },
            mouseLeave: function (e, link) { link.findObject('HIGHLIGHT').stroke = 'transparent' },
            selectionAdorned: false
          },
          new go.Binding('points').makeTwoWay(),
          this.$(go.Shape,
            { isPanelMain: true, strokeWidth: 4, stroke: 'transparent', name: 'HIGHLIGHT' }),
          this.$(go.Shape,
            { isPanelMain: true, stroke: 'gray', strokeWidth: 1 },
            new go.Binding('stroke', 'isSelected', function (sel) { return sel ? 'dodgerblue' : 'gray' }).ofObject()),
          this.$(go.Shape,
            { toArrow: 'standard', strokeWidth: 0, fill: '#cccccc' }),
          this.$(go.Panel, 'Auto',
            { visible: false, name: 'LABEL', segmentIndex: 2, segmentFraction: 0.5 },
            new go.Binding('visible', 'visible').makeTwoWay(),
            this.$(go.Shape, 'Circle',
              { fill: '#F8F8F8', strokeWidth: 1, stroke: '#cccccc' }),
            this.$(go.TextBlock, '真',
              { editable: true },
              new go.Binding('text').makeTwoWay())
          )
        )

      // 不知道干嘛
      this.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal
      this.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal

      // 拖拽面板
      let myPalette = this.$(go.Palette, this.$refs.baseCompContent,
        {
          scrollsPageOnFocus: false,
          nodeTemplate: this.$(go.Node, 'Auto', nodeStyle(),
            this.$(go.Panel, 'Auto',
              this.$(go.Shape, 'Rectangle',
                { margin: 3, strokeWidth: 0, width: 40, height: 40, fill: 'rgba(31, 96, 189, 0.05)' }
              ),
              this.$(go.Shape, 'Rectangle',
                { strokeWidth: 0, width: 25, height: 25, fill: '#1f60bd' },
                new go.Binding('geometry', 'geo', this.geoFunc))
            ),
            this.$(go.TextBlock, textStyle(),
              new go.Binding('text').makeTwoWay())
          ),

          model: new go.GraphLinksModel(myPalettes)
        })

      /**
      * 预置原件
      */

      let presetPalette = this.$(go.Palette, this.$refs.presetCompContent,
        {
          scrollsPageOnFocus: false,
          nodeTemplate: this.$(go.Node, 'Auto', nodeStyle(),
            this.$(go.Panel, 'Auto',
              this.$(go.Shape, 'Rectangle',
                { margin: 3, strokeWidth: 0, width: 40, height: 40, fill: 'rgba(31, 96, 189, 0.05)' }
              ),
              this.$(go.Shape, 'Rectangle',
                { strokeWidth: 0, width: 25, height: 25, fill: '#1f60bd' },
                new go.Binding('geometry', 'geo', this.geoFunc))
            ),
            this.$(go.TextBlock, textStyle(),
              new go.Binding('text').makeTwoWay())
          ),

          model: new go.GraphLinksModel(presetComp)
        })
    },

    showLinkLabel (e) {
      var label = e.subject.findObject('LABEL')
      if (label !== null) label.visible = (e.subject.fromNode.data.category === 'Conditional')
    },
    showContextMenu (obj, diagram, tool) {
      console.log(obj.data.category)
      this.currentNode = obj
      let cxElement = this.$refs.contextMenu
      let mousePt = diagram.lastInput.viewPoint
      cxElement.style.display = 'block'
      cxElement.style.left = mousePt.x + 'px'
      cxElement.style.top = mousePt.y + 'px'
      console.log(mousePt, mousePt.x, mousePt.y)
      // console.log(obj)
      // console.log(obj.findTreeParentNode())
    },
    geoFunc (geoname) {
      var geo = icons[geoname]
      if (geo === undefined) geo = icons['kaishi']
      if (typeof geo === 'string') {
        geo = icons[geoname] = go.Geometry.parse(geo, true)
      }
      return geo
    },
    getdata () { // 基本参数
      this.flowParamsComp = this.flowParamsComp || this.$createFlowParams({
      })
      this.flowParamsComp.show()
    },
    condition () { // 条件配置
      this.flowConditionComp = this.flowConditionComp || this.$createFlowCondition({
      })
      this.flowConditionComp.show()
    },
    nodeInData () { // 入参条件
      this.nodeInDataComp = this.nodeInDataComp || this.$createNodeInData({
      })
      this.nodeInDataComp.show()
    },
    // 数学运算
    arithmetic () {
      this.arithmeticComp = this.arithmeticComp || this.$createArithmetic({
      })
      this.arithmeticComp.show()
    },
    // 自定义转换
    customConversion () {
      this.customConversionComp = this.customConversionComp || this.$createCustomConversion({
      })
      this.customConversionComp.show()
    },
    /**
    * 计算上一个节点连了哪些
    */
    updateNode (data) {
      let prevNodeData = this.myDiagram.model.findNodeDataForKey(data.from)
      let nextNodeData = this.myDiagram.model.findNodeDataForKey(data.to)
      let link = Object.assign(Link, { target: nextNodeData.key })
      prevNodeData.next = [link]

      console.log(prevNodeData, nextNodeData)
    },
    /**
    * 保存最后数据
    */
    save () {
      console.log(this.myDiagram.model.nodeDataArray)
    }
  }
}
</script>
<style lang="stylus" scoped>
.m-content
  .bodyer
    display flex
    .palette-group
      width 108px
      border-right 1px solid #e8e8e8
      box-sizing border-box
      .group-title
        background-color: #edeff5
        text-align center
        height 20px
        line-height @height
      .comp
        margin 0 7px
        margin-top 10px
        .el-icon-arrow-right
          margin 0 8px 0 auto
          transition: transform .3s
          font-weight 300
          &.is-active
            transform: rotate(90deg);
      .comp-content
        margin 0 7px
        border-bottom 1px solid #e8e8e8
        margin-bottom 12px
        padding 10px 0
        height 400px
    .diagramContent
      position relative
      flex 1
      border-right 1px solid #e8e8e8
      border-bottom 1px solid #e8e8e8
      .diagram
        height 70vh
      .btns
        text-align center
        margin-top 15px
      .contextMenu
        position absolute
        z-index 999
        display none
        ul
          background #ffffff
          width: 120px;
          box-shadow: 0px 1px 4px 0px rgba(12, 44, 91, 0.22);
          border-radius: 3px;
          border: solid 1px #d5e1f3;
          list-style none
          li
            a
              display block
              color #666666
              font-size 12px
              height 27px
              line-height @height
              padding 0 7px
              cursor pointer
              &:hover
                background-color: #f4f7fc;
                border-radius: 3px;
                color #1f60bd
              i
                margin-right 5px
</style>
